(display "\n========================================\n")
(define m (list (list 1 2 3 4) (list 4 5 6 6) (list 6 7 8 9)))
(define v (list 1 2 3 4))
(display m)
(newline)
(define (accumulate op initial sequence)
    (if (null? sequence)
        initial
        (op (car sequence)
            (accumulate op initial (cdr sequence)))))

(define (accumulate-n op init seqs)
    (define (car-n s)
        (map car s))

    (define (cdr-n s)
        (map cdr s))
    (if (null? (car seqs))
        '()
        (cons (accumulate op init (car-n seqs))
              (accumulate-n op init (cdr-n seqs)))))

(define (dot-product v w)
    (accumulate + 0 (map * v w)))

(define (matrix-*-vector m v)
    (map (lambda (col)
                (dot-product col v))
        m))
(display (matrix-*-vector m v))
(newline)

(define (transpose mat)
    (accumulate-n cons '() mat))
(display (transpose m))
(newline)

(define (matrix-*-matrix m n)
    (let ((cols (transpose n)))
        (map (lambda (col-of-m)
                    (map (lambda (col-of-cols)
                                (dot-product col-of-m
                                             col-of-cols))
                        cols))
            m)))

(display (matrix-*-matrix m (transpose m)))
(newline)

(display "\n========================================\n")
